package io.github.stary1993.kite.auth.support.handler;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import io.github.stary1993.kite.core.constant.CommonConstants;
import io.github.stary1993.kite.security.handler.AuthenticationFailureEventHandler;
import io.github.stary1993.kite.syslog.config.SysLogTypeEnum;
import io.github.stary1993.kite.syslog.event.SysLogEvent;
import io.github.stary1993.kite.syslog.event.SysLogEventSource;
import io.github.stary1993.kite.syslog.util.SysLogUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 自定义认证失败处理
 * @author stary1993
 */
@Slf4j
public class CustomAuthenticationFailureEventHandler extends AuthenticationFailureEventHandler {

	/**
	 * @param request
	 * @param response
	 * @param exception
	 * @throws IOException
	 */
	@Override
	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
		String username = request.getParameter(OAuth2ParameterNames.USERNAME);
		log.info("用户：{} 登录失败，异常：{}", username, exception.getLocalizedMessage());
		SysLogEventSource sysLogEventSource = SysLogUtils.getSysLog();
		sysLogEventSource.setTitle("登录失败");
		sysLogEventSource.setLogType(SysLogTypeEnum.ERROR);
		sysLogEventSource.setException(exception.getLocalizedMessage());
		// 发送异步日志事件
		String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
		if (StrUtil.isNotBlank(startTimeStr)) {
			Long startTime = Long.parseLong(startTimeStr);
			Long endTime = System.currentTimeMillis();
			sysLogEventSource.setExecutionTime(endTime - startTime);
		}
		sysLogEventSource.setBody(username);
		SpringUtil.publishEvent(new SysLogEvent(sysLogEventSource));
		super.onAuthenticationFailure(request, response, exception);
	}

}
